package com.cloud.phone.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.net.VpnService
import android.os.Build
import android.os.ParcelFileDescriptor
import android.text.TextUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.cloud.phone.R
import com.cloud.phone.constants.Constants
import com.cloud.phone.task.SendMsgUtils
import com.cloud.phone.task.bean.ProxyInfoBean
import com.cloud.phone.task.bean.StopVpnMsg
import com.cloud.phone.utils.ProxyUtils
import com.cloud.phone.view.TsUtils
import engine.Engine
import engine.Key
import okhttp3.internal.closeQuietly
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.IOException
import java.util.concurrent.Executors


/**
 * @auth: njb
 * @date: 2024/4/30 11:13
 * @desc: vpn服务
 */
class CloudVpnService : VpnService() {
    private val TAG: String = CloudVpnService::class.java.getSimpleName()
    private val executors = Executors.newFixedThreadPool(5)
    var parcelFileDescriptor: ParcelFileDescriptor? = null

    override fun onCreate() {
        if(!EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().register(this)
        }
        LogUtils.d(TAG, "===vpn服务创建===")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return if (intent?.action == Constants.ACTION_DISCONNECT) {
            disconnect()
            START_NOT_STICKY
        } else {
            connect()
            START_STICKY
        }
    }

    override fun onDestroy() {
        LogUtils.d(TAG, "===vpn服务停止===")
        if(EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().unregister(this)
        }
    }

    private fun connect() {
        LogUtils.d(TAG, "===开始代理===onConnect")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            updateForegroundNotification()
        }
        // Become a foreground service. Background services can be VPN services too, but they can
        // be killed by background check before getting a chance to receive onRevoke().
        try {
            if(parcelFileDescriptor==null) {
                val builder: Builder = Builder()
                    .addAddress(Constants.ADDRESS, 24)
                    .addRoute(Constants.ROUTE, 0)
                    .addDnsServer(Constants.DNS)
                    //添加代理白名单应用
                    .addDisallowedApplication("com.cloud.phone")
                    //添加代理黑名单应用
                    //.addDisallowedApplication("com.huawei.cloudapp")
                    .setSession("cloudphone")
                // let DNS queries bypass VPN if SOCKS server does not support UDP bind
                ProxyUtils.addRoutesExcept(builder, Constants.DNS, 32)
                parcelFileDescriptor = builder.establish()
            }
            createVpnEngine()
            Constants.IS_MY_VPN_SERVICE_RUNNING = true
        } catch (e: Exception) {
            e.printStackTrace()
            if(parcelFileDescriptor!=null){
                parcelFileDescriptor!!.closeQuietly()
            }
        }
    }

    private fun createVpnEngine() {
        try {
            val key = Key()
            key.mark = 0
            key.mtu = 0
            key.device = "fd://" + parcelFileDescriptor?.fd // <--- here
            key.setInterface("")
            key.logLevel = "debug"
            if (!TextUtils.isEmpty(ProxyUtils.getSocksUrl())) {
                key.proxy = ProxyUtils.getSocksUrl() // <--- and here
            }
            TsUtils.showTips("代理IP已开启:"+ProxyUtils.getProxyIp())
            key.restAPI = ""
            key.tcpSendBufferSize = ""
            key.tcpReceiveBufferSize = ""
            key.tcpModerateReceiveBuffer = false
            Engine.insert(key)
            executors.submit(Engine::start)
            val socksArray = ProxyUtils.getSocksUrl()
            sendMsgToServer(socksArray)
        } catch (e: Exception) {
            e.printStackTrace()
            if(parcelFileDescriptor!=null){
                parcelFileDescriptor!!.closeQuietly()
            }
        }
    }



    private fun sendMsgToServer(socksArray: String?) {
        try {
            val proxyInfoBean = ProxyInfoBean()
            if (socksArray?.isNotEmpty() == true) {
                val socks = socksArray.split(":")
                socks.let {
                    proxyInfoBean.apply {
                        this.account = it[0]
                        this.password = socks[1].split("@")[0]
                        this.ip = socks[1].split("@")[1]
                        this.port = socks[2].toInt()
                        LogUtils.d(TAG, "===代理地址为===" + this.ip)
                        TsUtils.showTips("===代理地址为===${this.ip}")
                    }
                }
            }
            LogUtils.d(TAG, "===设置的vpn状态为3333===" + Constants.IS_MY_VPN_SERVICE_RUNNING)
            Constants.TASK_STATUS = true
            Constants.TASK_IS_RUNNING = true
            proxyInfoBean.id = ProxyUtils.getTaskId()
            LogUtils.d(TAG, "===发送给服务器的信息为===${GsonUtils.toJson(proxyInfoBean)}")
            SendMsgUtils.sendMsgBean(proxyInfoBean)
        }catch (e:Exception){
            e.printStackTrace()
        }
    }


    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    fun stopVpnMsgGet(stopVpnMsg: StopVpnMsg){
        disconnect()
    }


    fun disconnect() {
        //停止vpn代理引擎
        TsUtils.showTips("正在停止VPN")
        LogUtils.d(TAG, "===停止代理===onDisconnect")
        if (parcelFileDescriptor != null) {
            try {
                ProxyUtils.setSocksUrl("")
                ProxyUtils.setProxyIp("")
                parcelFileDescriptor!!.close()
                onRevoke()
                stopForeground(true)
                stopSelf()
                parcelFileDescriptor=null
                Constants.IS_MY_VPN_SERVICE_RUNNING = false
                TsUtils.showTips("已退出代理")
            } catch (e: IOException) {
                e.printStackTrace()
                TsUtils.showTips("停止VPN出错"+e.cause)
            }
        }else{
            TsUtils.showTips("VPN未连接")
        }
    }


    private fun updateForegroundNotification() {
        val channelId = "cloud100"
        val channelName = "cloud-phone"
        val notifyId = 200
        val mNotificationManager = getSystemService(
            NOTIFICATION_SERVICE
        ) as NotificationManager
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                mNotificationManager.createNotificationChannel(
                    NotificationChannel(
                        channelId, channelName,
                        NotificationManager.IMPORTANCE_DEFAULT
                    )
                )
                startForeground(
                    notifyId, Notification.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_launcher_background)
                        // .setContentText(getString(message))
                        //  .setContentIntent(mConfigureIntent)
                        .build()
                )
            }
        }
    }


}